package com.szcinda.fitness.security;

import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

@Component
public class JwtAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {


    @Override
    public boolean supports(Class<?> authentication) {
        return (JwtAuthenticationToken.class.isAssignableFrom(authentication));
    }

    @Override
    protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
    }

    @Override
    protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
        JwtAuthenticationToken jwtAuthenticationToken = (JwtAuthenticationToken) authentication;
        String token = jwtAuthenticationToken.getToken();
        String currentOrganization = jwtAuthenticationToken.getCurrentOrganization();

        if (!StringUtils.isEmpty(token)) {

            JwtUserDto parsedUser = JwtTokenUtils.parseToken(token);

            if (parsedUser == null) {
                throw new JwtTokenMalformedException("JWT token is not valid");
            }

            AuthenticatedUser authenticatedUser = new AuthenticatedUser();
            authenticatedUser.setId(parsedUser.getId());
            authenticatedUser.setUsername(parsedUser.getUsername());
            authenticatedUser.setName(parsedUser.getName());
            authenticatedUser.setOrganization(parsedUser.getOrganizationId());
            authenticatedUser.setCurrentOrganization(currentOrganization);
            authenticatedUser.setRootOrganizationId(parsedUser.getRootOrganizationId());
            authenticatedUser.setRoles(parsedUser.getRoles());
            authenticatedUser.setLocked(false);
            return authenticatedUser;
        }

        return null;
    }

}
